#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

class ComponentWithContextualHelp
{
public:
    virtual bool showHelp(std::string text) = 0;
};

class Container;
class Component : public ComponentWithContextualHelp
{
protected:
    Container* container = nullptr;
    std::string name;
public:
    Component(std::string name_)
    :name(name_)
    {
    }
    void setParent(Container* container_)
    {
        container = container_;
    }
    bool showHelp(std::string text) override;
};

class Container : public Component
{
protected:
    std::vector<Component*> children;
public:
    Container(std::string name)
    :Component(name)
    {
    }
    bool showHelp(std::string text) override
    {
        if(name == text)
        {
            std::cout<<"Container "<<name<<" show help"<<std::endl;
            return true;
        }
        else{
            for(auto c : children)
            {
                if(c->showHelp(text))
                    return true;
            }
        }
        return false;
    }
    void add(Component* child)
    {
        child->setParent(this);
        children.push_back(child);
    }
};

bool Component::showHelp(std::string text)
{
    if(name == text)
    {
        std::cout<<"Component "<<name<<" show help"<<std::endl;
        return true;
    } else{
        return false;
    }
}

class Panel : public Container
{
public:
    Panel(std::string name)
    :Container(name)
    {

    }
    bool showHelp(std::string text) override
    {
        if(name == text)
        {
            std::cout<<"Panel "<<name<<" show help"<<std::endl;
            return true;
        }
        else{
            for(auto c : children)
            {
                if(c->showHelp(text))
                    return true;
            }
        }
        return false;
    }
};


class Dialog : public Container
{
public:
    Dialog(std::string name)
    :Container(name)
            {

            }
    bool showHelp(std::string text) override
    {
        if(name == text)
        {
            std::cout<<"Dialog "<<name<<" show help"<<std::endl;
            return true;
        }
        else{
            for(auto c : children)
            {
                if(c->showHelp(text))
                    return true;
            }
        }
        return false;
    }
};

class Button : public Component
{
public:
    Button(std::string name_)
    :Component(name_)
    {
    }
    bool showHelp(std::string text) override
    {
        if(name == text)
        {
            std::cout<<"Button "<<name<<" show help"<<std::endl;
            return true;
        }
        return false;
    }
};

int main() {
    Dialog *dialog = new Dialog("dialog");
    Panel *panel = new Panel("panel");
    Button *ok = new Button("ok");
    Button *cancel = new Button("cannel");
    panel->add(ok);
    panel->add(cancel);
    dialog->add(panel);
    dialog->showHelp("ok");
    return 0;
}

